from docx import Document
from docx.oxml import OxmlElement
from docx.shared import Inches, Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING
from docx.enum.section import WD_ORIENT, WD_SECTION
from docx.oxml.ns import qn
import pandas as pd
from func.docxs.static_style.one import predefined_styles
import re
# 注意当你使用header
# 注意文本居中位置位置该怎么处理
class InitDocument:
    def __init__(self, filename, root_path, global_style=None):
        self.root_path = root_path
        self.filename = filename
        self.document = Document()
        self.paragraphs = []
        self.global_style = global_style if global_style else predefined_styles

    def judge_paragraphs_len(self, input_string):
        paragraphs = re.split(r'(?:\r?\n){1,}', input_string)
        paragraphs = [p.strip() for p in paragraphs if p.strip()]
        return  paragraphs,len(paragraphs)

    def add_paragraph(self, text, style_name='Normal'):
        style = self.global_style.get(style_name, self.global_style['Normal'])
        font_name = style['font']['name']
        font_size = style['font']['size']
        font_color = style['font']['color']
        underline = style['font']['underline']
        alignment = style['font']['alignment']
        line_spacing = style.get('line_spacing', None)
        first_line_indent = style.get('first_line_indent', 0)

        p = self.document.add_paragraph()
        p.paragraph_format.first_line_indent = first_line_indent
        if line_spacing:
            p.paragraph_format.line_spacing_rule = WD_LINE_SPACING.EXACTLY
            p.paragraph_format.line_spacing = line_spacing

        run = p.add_run(text)
        run.font.name = font_name
        run.font.size = font_size
        run.font.color.rgb = font_color
        run.font.underline = underline

        if alignment == 'center':
            p.alignment = WD_ALIGN_PARAGRAPH.CENTER
        elif alignment == 'right':
            p.alignment = WD_ALIGN_PARAGRAPH.RIGHT
        else:
            p.alignment = WD_ALIGN_PARAGRAPH.LEFT

        self.paragraphs.append(p)

    def add_paragraph_with_runs(self, text_parts, style_names):
        p = self.document.add_paragraph()
        for text, style_name in zip(text_parts, style_names):
            style = self.global_style.get(style_name, self.global_style['Normal'])
            font_name = style['font']['name']
            font_size = style['font']['size']
            font_color = style['font']['color']
            underline = style['font']['underline']
            alignment = style['font']['alignment']
            background_color = style.get('background_color', 'FFFFFF')

            run = p.add_run(text)
            run.font.name = font_name
            run.font.size = font_size
            run.font.color.rgb = font_color
            run.font.underline = underline

            self.set_background_color(run, background_color)

        return p

    def set_background_color(self, run, hex_color):
        r = run._r
        rPr = r.get_or_add_rPr()
        shd = OxmlElement('w:shd')
        shd.set(qn('w:fill'), hex_color)
        rPr.append(shd)

    def add_image(self, image_path, width=1.25, height=1.25, style_name='Normal'):
        style = self.global_style.get(style_name, self.global_style['Normal'])
        run = self.document.add_paragraph().add_run()
        run.add_picture(image_path, width=Inches(width), height=Inches(height))
        run.font.name = style['font']['name']
        run.font.size = style['font']['size']
        run.font.color.rgb = style['font']['color']
        run.font.underline = style['font']['underline']

    def add_table(self, data, style='Table Grid'):
        df = pd.DataFrame(data)
        table = self.document.add_table(rows=(df.shape[0] + 1), cols=df.shape[1], style=style)

        for col_idx, col_name in enumerate(df.columns):
            table.cell(0, col_idx).text = str(col_name)

        for row_idx, row_data in df.iterrows():
            for col_idx, cell_data in enumerate(row_data):
                table.cell(row_idx + 1, col_idx).text = str(cell_data)

    def add_header(self, text, level=None, style_name='Heading1'):
        style = self.global_style.get(style_name, self.global_style['Normal'])

        header =None
        alignment = style['font']['alignment']
        if not level:
            header=self.document.add_paragraph()
            header_run=header.add_run(text)

        else:
            header = self.document.add_heading(level=level)
            header_run=header.add_run(text)
        header_run.font.name = style['font']['name']
        header_run.font.size = style['font']['size']
        header_run.font.color.rgb = style['font']['color']
        header_run.font.underline = style['font']['underline']
        if alignment == 'center':
            header.alignment = WD_ALIGN_PARAGRAPH.CENTER
        elif alignment == 'right':
            header.alignment = WD_ALIGN_PARAGRAPH.RIGHT
        else:
            header.alignment = WD_ALIGN_PARAGRAPH.LEFT

    def add_page_break(self, orientation='portrait', section_type=WD_SECTION.NEW_PAGE):
        new_section = self.document.add_section(section_type)
        if orientation == 'landscape':
            new_section.orientation = WD_ORIENT.LANDSCAPE
            new_section.page_width, new_section.page_height = new_section.page_height, new_section.page_width

    def save(self):
        path = f"{self.root_path}/{self.filename}"
        self.document.save(path)
        return path




if __name__ == "__main__":

    doc = InitDocument("example.docx", "./output")
    doc.add_header("初始标题一级标题", level=1, style_name='Heading1')
    doc.add_paragraph("全局样式.", style_name='Normal')
    doc.add_paragraph("自定义一级标题-段落", style_name='Heading1')
    doc.add_paragraph("自定义二级标题-段落", style_name='Heading2')
    doc.add_paragraph("自定义1", style_name='CustomStyle1')
    doc.add_paragraph("Quote样式", style_name='Quote')
    doc.add_paragraph("代码样式", style_name='Code')
    doc.add_paragraph("自定义标题", style_name='Title')
    doc.add_paragraph("字幕", style_name='Subtitle')
    doc.add_paragraph_with_runs(
        ["分割1", "分割2 ", "分割3", "分割4"],
        ['Normal', 'Emphasis', 'Highlight', 'CustomStyle1']
    )
    doc.add_image(image_path="../../public/yonghu.png", width=2.0, height=2.0, style_name='Normal')
    doc.add_table(data={
        'Header1': ['11', '21'],
        'Header2': ['12', '22']
    }, style='Table Grid')
    doc.add_page_break(orientation='landscape')
    path = doc.save()
    print(f"Document saved at: {path}")